/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include "sle_tool.h"
#include "sle_hilog.h"
#include <unistd.h>
#include <signal.h>


static SleErrorCode InitSleTool(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleHostService();
    if(ret != SLE_NO_ERROR) return ret;
    ret = InitSleAnnounceService();
    if(ret != SLE_NO_ERROR) return ret;
    ret = InitSleSeekService();
    if(ret != SLE_NO_ERROR) return ret;
    ret = InitSleConnectService();
    if(ret != SLE_NO_ERROR) return ret;
    ret = InitSleSsapsService();
    if(ret != SLE_NO_ERROR) return ret;
    ret = InitSleSsapcService();
    if(ret != SLE_NO_ERROR) return ret;
    return SLE_NO_ERROR;
}

static SleErrorCode RegisterSleToolCbs(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = RegisterHostCallbacks(&g_hostToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    ret = RegisterAnnounceCallbacks(&g_announceToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    ret = RegisterConnectCallbacks(&g_connectToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    return SLE_NO_ERROR;
}

static SleErrorCode UnregisterSleToolCbs(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;

    ret = UnregisterAnnounceCallbacks(&g_announceToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    ret = UnregisterConnectCallbacks(&g_connectToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    ret = UnregisterHostCallbacks(&g_hostToolCbs);
    if(ret != SLE_NO_ERROR) return ret;

    return SLE_NO_ERROR;
}

static void SleHostTool(void)
{
    SleToolHandler(g_hostCmdList, g_hostCmdNum);
}

static void SleAnnounceTool(void)
{
    SleToolHandler(g_announceCmdList, g_announceCmdNum);
}

static void SleSeekTool(void)
{
    SleErrorCode ret = RegisterSeekCallbacks(&g_seekToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSeekCallbacks fail(%d)", ret);
        return;
    }
    SleToolHandler(g_seekCmdList, g_seekCmdNum);
    ret = UnregisterSeekCallbacks(&g_seekToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterSeekCallbacks fail(%d)", ret);
    }
}

static void SleConnectTool(void)
{
    SleToolHandler(g_connectCmdList, g_connectCmdNum);
}

static void SleSsapServerTool(void)
{
    SleErrorCode ret = RegisterSsapServerCallbacks(&g_ssapsToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSsapServerCallbacks fail(%d)", ret);
        return;
    }
    SleToolHandler(g_ssapServerCmdList, g_ssapServerCmdNum);
    ret = UnregisterSsapServerCallbacks(&g_ssapsToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterSsapServerCallbacks fail(%d)", ret);
    }
}

static void SleSsapClientTool(void)
{
    SleErrorCode ret = RegisterSsapClientCallbacks(&g_ssapcToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSsapClientCallbacks fail(%d)", ret);
        return;
    }
    SleToolHandler(g_ssapClientCmdList, g_ssapClientCmdNum);
    ret = UnregisterSsapClientCallbacks(&g_ssapcToolCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterSsapClientCallbacks fail(%d)", ret);
    }
}

static void SleDelayTestServerTool(void)
{
    SleErrorCode ret = RegisterSsapServerCallbacks(&g_ssapsToolDelayLiteCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSsapServerCallbacks fail(%d)", ret);
        return;
    }
    ret = RegisterConnectCallbacks(&g_connectToolDelayLiteCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterConnectCallbacks server fail(%d)", ret);
        return;
    }

    SleToolHandler(g_ssapServerDelayCmdList, g_ssapServerDelayCmdNum);

    ret = UnregisterSsapServerCallbacks(&g_ssapsToolDelayLiteCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterSsapServerCallbacks fail(%d)", ret);
    }
    ret = UnregisterConnectCallbacks(&g_connectToolDelayLiteCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterConnectCallbacks server fail(%d)", ret);
    }
}

static void SleDelayTestClientTool(void)
{
    SleErrorCode ret = RegisterSsapClientCallbacks(&g_ssapcToolDelayCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSsapClientCallbacks fail(%d)", ret);
        return;
    }
    ret = RegisterConnectCallbacks(&g_connectToolDelayCbs);
    if(ret != SLE_NO_ERROR) {
        printf("RegisterConnectCallbacks client fail(%d)", ret);
        return;
    }

    SleToolHandler(g_ssapClientDelayCmdList, g_ssapClientDelayCmdNum);

    ret = UnregisterSsapClientCallbacks(&g_ssapcToolDelayCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterSsapClientCallbacks fail(%d)", ret);
    }
    ret = UnregisterConnectCallbacks(&g_connectToolDelayCbs);
    if(ret != SLE_NO_ERROR) {
        printf("UnregisterConnectCallbacks client fail(%d)", ret);
    }
}
static void SleToolTestHalper(void);
static CmdNode  g_sleToolCmdList[] = {
    {"SleToolHalper", SleToolTestHalper},
    {"SleHostTool", SleHostTool},
    {"SleAnnounceTool", SleAnnounceTool},
    {"SleSeekTool", SleSeekTool},
    {"SleConnectTool", SleConnectTool},
    {"SleSsapServerTool", SleSsapServerTool},
    {"SleSsapClientTool", SleSsapClientTool},
    {"SleDelayTestServerTool", SleDelayTestServerTool},
    {"SleDelayTestClientTool", SleDelayTestClientTool},
};
static uint16_t g_sleToolCmdNum = sizeof(g_sleToolCmdList) / sizeof(CmdNode);

static void SleToolHalper(CmdNode* cmdList, uint16_t cmdNum)
{
    printf("*********SleTool Command List*********\r\n");
    for (uint16_t i = 0; i < cmdNum; i++) {
        printf("*     %02d - %-20s     *\r\n", i, cmdList[i].desc);
    }
    printf("************-1: return****************\r\n");
}

static void SleToolHandler(CmdNode* cmdList, uint16_t cmdNum)
{
    while (1) {
        SleToolHalper(cmdList, cmdNum);
        int cmd = 0;
        scanf("%d", &cmd);
        ClearInputBuffer();
        if(cmd == -1) break;
        cmdList[cmd].func();
    }
}

void SleToolTestHalper(void)
{
    SleToolHalper(g_sleToolCmdList, g_sleToolCmdNum);
}

void SleToolSigHandle(int sig) {
    printf("please input -1 to return to home and exit");
#if 0 //Todo: 死亡监听机制实现后可用SIGINT退出,否则有回调未去注册问题
    SleErrorCode ret = UnregisterSleToolCbs();
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSleToolCbs fail\r\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
#endif
}

int main (void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleTool();
    if(ret != SLE_NO_ERROR) {
        printf("InitSleTool fail\r\n");
        goto end;
    }
    ret = RegisterSleToolCbs();
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSleToolCbs fail\r\n");
        goto end;
    }
    signal(SIGINT, SleToolSigHandle);
    while(1) {
        SleToolHalper(g_sleToolCmdList, g_sleToolCmdNum);
        int cmdNum = 0;
        scanf("%d", &cmdNum);
        ClearInputBuffer();
        if(cmdNum == -1) break;
        g_sleToolCmdList[cmdNum].func();
    }
end:
    printf("sle_tool end");
    ret = UnregisterSleToolCbs();
    if(ret != SLE_NO_ERROR) {
        printf("RegisterSleToolCbs fail\r\n");
    }
    return 0;
}

#ifdef __cplusplus
}
#endif // __cplusplus